package com.tootallgavin.uttt;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class tttView extends View {
    private final Bitmap mBmpPlayer1;
    private final Paint mWinPaint;
    private Paint mLinePaint;
    private static final int MARGIN = 4;
    private int mSxy;
    private int mOffetX;
    private int mOffetY;
    private final Rect mDstRect = new Rect();
    private final Rect mSrcRect = new Rect();
    private State[] mSquares = new State[9];
    private Paint mBmpPaint;
    private tttViewListener mtttViewListener;
    private int mWinCol;
    private State mWinner;
    private int mWinRow;
    private int mWinDiag;

    public boolean checkGameFinished() {

        State[] data = mSquares;
        boolean full = true;
        State winner = State.EMPTY;

        int col = -1;
        int row = -1;
        int diag = -1;

        // check rows
        for (int j = 0, k = 0; j < 3; j++, k += 3) {
            if (data[k] != State.EMPTY && data[k] == data[k + 1] && data[k] == data[k + 2]) {
                row = j;
                winner = data[k];
            }
            if (full && (data[k] == State.EMPTY ||
                    data[k + 1] == State.EMPTY ||
                    data[k + 2] == State.EMPTY)) {
                full = false;
            }
        }

        // check columns
        for (int i = 0; i < 3; i++) {
            if (data[i] != State.EMPTY && data[i] == data[i + 3] && data[i] == data[i + 6]) {
                col = i;
                winner = data[i];
            }
        }

        // check diagonals
        if (data[0] != State.EMPTY && data[0] == data[1 + 3] && data[0] == data[2 + 6]) {
            diag = 0;
            winner = data[0];
        } else if (data[2] != State.EMPTY && data[2] == data[1 + 3] && data[2] == data[0 + 6]) {
            diag = 1;
            winner = data[2];
        }

        if (col != -1 || row != -1 || diag != -1) {
            Log.v("uttt","check")  ;
            setFinished(winner, col, row, diag);
            return true;
        }

        // if we get here, there's no winner but the board is full.
        if (full) {
            setFinished(State.EMPTY, -1, -1, -1);
            return true;
        }
        return false;
    }

    public void settttViewListener(tttViewListener mtttViewListener) {
        this.mtttViewListener = mtttViewListener;
    }

    public void setBoard(int mSelectedBigCell, State[][] mSmallSquares) {

        mSquares = mSmallSquares[mSelectedBigCell];
        checkGameFinished();
    }


    public interface tttViewListener {
        public void onSquareSelected(int cell);
    }


    public tttView(Context context) {
        super(context);

        mBmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint = new Paint();
        mWinner = State.EMPTY;
        mWinCol = -1;
        mWinRow = -1;
        mWinDiag = -1;
        mLinePaint.setColor(0xFFFFFFFF);
        mLinePaint.setStrokeWidth(5);
        mLinePaint.setStyle(Paint.Style.STROKE);
        mBmpPlayer1 = getResBitmap(R.drawable.blue);
        mSrcRect.set(0, 0, mBmpPlayer1.getWidth() - 1, mBmpPlayer1.getHeight() - 1);


        mWinPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mWinPaint.setColor(0xFFFF0000);
        mWinPaint.setStrokeWidth(10);
        mWinPaint.setStyle(Paint.Style.STROKE);

        setVisibility(INVISIBLE);
        setBackgroundColor(0xFF00FF00);
        setAlpha((float) 1);

        for (int i = 0; i < mSquares.length; mSquares[i++] = State.EMPTY);




    }

    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();

        if (action == MotionEvent.ACTION_DOWN)
            return true;
        else if (action == MotionEvent.ACTION_UP) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            int sxy = mSxy;
            x = (x - MARGIN) / sxy;
            y = (y - MARGIN) / sxy;
            int cell = (x + 3 * y) - 3;
            mtttViewListener.onSquareSelected(cell);
        }

        return true;
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int sxy = mSxy;
        int s3 = sxy * 3 - 1;
        int x7 = mOffetX;
        int y7 = mOffetY;
        //big lines
        for (int i = 0, k = sxy; i < 2; i++, k += sxy) {
            canvas.drawLine(x7, y7 + k, x7 + s3, y7 + k, mLinePaint);
            canvas.drawLine(x7 + k, y7, x7 + k, y7 + s3, mLinePaint);
        }

        mLinePaint.setStyle(Paint.Style.FILL);

        for (int j = 0, k = 0, y = y7; j < 3; j++, y += sxy) {
            for (int i = 0, x = x7; i < 3; i++, k++, x += sxy) {
                if (mSquares[k] == State.PLAYER1) {
                    mDstRect.offsetTo(MARGIN + x, MARGIN + y);
                    canvas.drawBitmap(mBmpPlayer1, mSrcRect, mDstRect, mBmpPaint);
                }
            }
        }


        if (mWinRow >= 0) {
            int y = y7 + mWinRow * sxy + sxy / 2;
            canvas.drawLine(x7 + MARGIN, y, x7 + s3 - 1 - MARGIN, y, mWinPaint);

        } else if (mWinCol >= 0) {
            int x = x7 + mWinCol * sxy + sxy / 2;
            canvas.drawLine(x, y7 + MARGIN, x, y7 + s3 - 1 - MARGIN, mWinPaint);

        } else if (mWinDiag == 0) {
            // diagonal 0 is from (0,0) to (2,2)

            canvas.drawLine(x7 + MARGIN, y7 + MARGIN,
                    x7 + s3 - 1 - MARGIN, y7 + s3 - 1 - MARGIN, mWinPaint);

        } else if (mWinDiag == 1) {
            // diagonal 1 is from (0,2) to (2,0)

            canvas.drawLine(x7 + MARGIN, y7 + s3 - 1 - MARGIN,
                    x7 + s3 - 1 - MARGIN, y7 + MARGIN, mWinPaint);
        }
    }
    public void setFinished(State winner, int col, int row, int diagonal) {
        mWinner = winner;
        mWinCol = col;
        mWinRow = row;
        mWinDiag = diagonal;
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int sx = (w - 2 * MARGIN) / 3;
        int sy = (h - 2 * MARGIN) / 3;

        int size = sx < sy ? sx : sy;

        mSxy = size;
        mOffetX = (w - 3 * size) / 2;
        mOffetY = (h - 3 * size) / 2;

        mDstRect.set(MARGIN, MARGIN, size - MARGIN, size - MARGIN);
    }

    private Bitmap getResBitmap(int bmpResId) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inDither = false;

        Resources res = getResources();
        Bitmap bmp = BitmapFactory.decodeResource(res, bmpResId, opts);

        if (bmp == null && isInEditMode()) {
            // BitmapFactory.decodeResource doesn't work from the rendering
            // library in Eclipse's Graphical Layout Editor. Use this workaround instead.

            Drawable d = res.getDrawable(bmpResId);
            int w = d.getIntrinsicWidth();
            int h = d.getIntrinsicHeight();
            bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(bmp);
            d.setBounds(0, 0, w - 1, h - 1);
            d.draw(c);
        }

        return bmp;
    }
}
